/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.maixiami;

import com.sleepycat.je.DatabaseException;
import com.taobao.api.ApiException;
import com.taobao.api.domain.Item;
import com.taobao.api.domain.ItemCat;
import com.taobao.api.domain.TaobaokeShop;
import com.taobao.api.domain.User;
import com.taobao.api.request.ItemsGetRequest;
import com.taobao.api.response.ItemsGetResponse;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import org.apache.log4j.Logger;

/**
 *
 * @author 叶勤勇
 */
public class TaobaoUserShopConnector {
    private static Logger logger = Logger.getLogger(TaobaoUserShopConnector.class);
    
    private Map<Long, TaobaokeShop> shopMap;
    private List<User> users;
    ItemCategories<ItemCat> itemCats;
    
    public TaobaoUserShopConnector(String userFile, String shopFile, String catFile) throws FileNotFoundException, IOException, ClassNotFoundException {
        // get users from userfile
        users = new ArrayList<User>();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(userFile));
        try {
            while(true) {
                Object obj = ois.readObject();
                if(obj == null)
                    break;
                users.add((User)obj);
            }
        } catch(IOException ex) {           
            logger.warn(ex);
        } catch(ClassNotFoundException ex) { 
            logger.warn(ex);
        }
        ois.close();
        
        // get shops from shopfile
        List<TaobaokeShop> shops = (List<TaobaokeShop>)Utils.readObjectFromFile(shopFile);
        shopMap = new HashMap<Long, TaobaokeShop>();
        for(TaobaokeShop shop : shops) {
            shopMap.put(shop.getUserId(), shop);
        }
        
        // construct itemCategories
        itemCats = new ItemCategories((List<ItemCat>)Utils.readObjectFromFile(catFile));
    }
    
    public void connect() throws DatabaseException, InterruptedException {
        ItemsGetRequest req = new ItemsGetRequest();
        req.setFields("num_iid,volume,cid");
        req.setPageSize(100L);
        req.setOrderBy("volume:desc");
        StoreHelper helper = new StoreHelper("f:/taobao", "taobao");
        TaobaoUserAccessor accessor = new TaobaoUserAccessor(helper.getStore());
        for(User user : users) {
            req.setNicks(user.getNick());
            TaobaokeShop shop = shopMap.get(user.getUserId());
            if(shop != null) {
                try {
                    ItemsGetResponse res = App.getTaobaoClient().execute(req);
                    if(res.isSuccess() && res.getItems() != null) {
                        List<Long> majorCids = classify(res.getItems());
                        TaobaoUserEntity userEntity = new TaobaoUserEntity(user, shop);
                        userEntity.getCids().addAll(majorCids);
                        accessor.putTaobaoUserEntity(userEntity);
                    } else {
                        // retry once
                        res = App.getTaobaoClient().execute(req);
                        if(res.isSuccess() && res.getItems() != null) {
                            List<Long> majorCids = classify(res.getItems());
                            TaobaoUserEntity userEntity = new TaobaoUserEntity(user, shop);
                            userEntity.getCids().addAll(majorCids);
                            accessor.putTaobaoUserEntity(userEntity);
                        } else {
                            logger.warn(res.getMsg());
                        }
                    }
                    Thread.sleep(100);
                } catch (ApiException ex) {
                    logger.warn(ex);
                }
            }
        }// end of for
        helper.close();
    }
    
    private List<Long> classify(List<Item> items) {
        Map<Long, Integer> cidCountMap = new TreeMap<Long, Integer>();
        for(Item item : items) {
            Long secondAncestor = itemCats.getSecondAncestor(item.getCid());
            Integer count = cidCountMap.get(secondAncestor);
            if(count != null)
                cidCountMap.put(secondAncestor, count + 1);
            else
                cidCountMap.put(secondAncestor, 1);
        }
        
        List<Long> majorCids = new ArrayList<Long>();
        for(Map.Entry<Long, Integer> entry : cidCountMap.entrySet()) {
            if(entry.getValue() * 10 > items.size())
                majorCids.add(entry.getKey());
        }
        
        return majorCids;
    }
}
